﻿using Dapper;
using System.Data;

namespace MediatRApp;

public class DbContext : IDisposable
{
    private readonly IDbConnection _connection;
    private DbContextTransction? _transction;

    public DbContext(IDbConnection connection)
    {
        _connection = connection;
    }

    public bool HasActiveTransaction => _transction != null;

    public DbContextTransction BeginTransction()
    {
        _connection.Open();
        _transction = new DbContextTransction(_connection.BeginTransaction());
        return _transction;
    }

    public void CommitTransction()
    {
        _transction?.CommitTransction();
        _transction = null;
    }

    public void Dispose()
    {
        _connection.Dispose();
    }

    public async Task ExecuteAsync(string sql, object? parameter = null)
    {
        await _connection.ExecuteAsync(sql, parameter, _transction?.GetDbTransaction());
    }

    public async Task<T> ExecuteScalar<T>(string sql, object? parameter = null)
    {
        return  await _connection.ExecuteScalarAsync<T>(sql, parameter, _transction?.GetDbTransaction());
    }

    public async Task<IEnumerable<T>> QueryAsync<T>(string sql, object? parameter = null)
    {
       return  await _connection.QueryAsync<T>(sql, parameter, _transction?.GetDbTransaction());
    }
}

public class DbContextTransction : IDisposable
{
    private IDbTransaction? _transction;
    private readonly bool isDisposed;

    public DbContextTransction(IDbTransaction transction)
    {
        _transction = transction;
    }

    public IDbTransaction? GetDbTransaction()
    {
        return _transction;
    }

    public void Dispose()
    {
        if (isDisposed)
        {
            return;
        }
        RollingTransction();
    }

    public void RollingTransction()
    {
        _transction?.Rollback();
        _transction = null;
    }

    public void CommitTransction()
    {
        _transction?.Commit();
        _transction = null;
    }



}